home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-02
/
pascala.zip
/
AIRPORT2.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1991-05-06
|
16KB
|
448 lines
PROGRAM Airort(Input, Output);
(********************************************************)
(* Pre-Cond: The user must supply the number of time *)
(* intervals, the arrival and departure *)
(* rates per time interval. *)
(* Post-Cond: The program performs a random simulation *)
(* of the airport, showing the summary of *)
(* various statistics and the log of run *)
(* use. *)
(* From Kruse, out of PRB 1/31/91 *)
(********************************************************)
(*****************************************)
(* Alejo Alamillo COSC 055 *)
(* Spring 1991 Assignment Airport *)
(*****************************************)
CONST QueueSize = 5;
TYPE PlaneRecType = RECORD
ID,
TimeOnQ: Integer;
END;
QueueEntry = PlaneRecType; (* Alias for QueuePack *)
QueueType = RECORD (* Array implementation *)
Count,
Front,
Rear: Integer;
Entry: ARRAY[0..QueueSize] OF QueueEntry;
END;
VAR LandingQ,
TakeoffQ: Queuetype;
CurrentPlane: PlaneRecType;
BackLog: Boolean;
Counter,
CurrentTime,
EndTime,
Seed,
NumberOfPlanes,
NumberOfLandings,
NumberOfTakeoffs,
NumberRefused,
TotalLandingWait,
TotalTakeoffWait,
MaximumLandingWait,
MaximumTakeoffWait,
Idletime,
IdletimeLand,
IdletimeTakeoff: Integer;
(*****************************************************************)
ExpectedArrivals,
ExpectedDepartures: Real;
(*********************************************************)
(* QUEUEPACK routines follow: *)
(*********************************************************)
(***********************************************)
(* Pre-Cond: None *)
(* Post-Cond: An empty Q has been created *)
(***********************************************)
PROCEDURE CreateQ( VAR Q: QueueType);
BEGIN
WITH Q DO
BEGIN
Count:= 0;
Front:= 1;
Rear:= 0;
END;
END;
(***********************************************)
(* Pre-Cond: The Queue has been created. *)
(* Post-Cond: Obvious. *)
(***********************************************)
FUNCTION FullQ(VAR Q: QueueType): Boolean;
BEGIN
IF ((Q.Rear + 2) MOD QueueSize = (Q.Front MOD QueueSize) ) THEN
FullQ:= True
ELSE
FullQ:= False;
END;
FUNCTION EmptyQ( VAR Q: QueueType): Boolean;
BEGIN
IF ((Q.Rear + 1) MOD QueueSize = (Q.Front MOD QueueSize)) THEN
EmptyQ:= True
ELSE
EmptyQ:= False;
END;
(***********************************************)
(* Pre-Cond: Q has been created *)
(* Post-Cond: Item has been added at the *)
(* rear of the Q *)
(***********************************************)
PROCEDURE Append(VAR Q: QueueType; NewItem: QueueEntry);
BEGIN
WITH Q DO
BEGIN
IF (not FullQ(Q)) THEN
BEGIN
Rear:= (Rear MOD QueueSize) + 1;
Entry[Rear]:= NewItem;
END
ELSE
Writeln('ERROR--Q overflow');
END;
END;
(**************************************************)
(* Pre-Cond: Q has been created *)
(* Post-Cond: The first item on the Q hs been *)
(* removed and copied to ItemFromQ *)
(**************************************************)
PROCEDURE Serve(VAR Q: QueueType; VAR ItemFromQ: QueueEntry);
BEGIN
WITH Q DO
BEGIN
IF (not EmptyQ(Q)) THEN
BEGIN
Count:= Count - 1;
ItemFromQ:= Entry[Front];
Front:= (Front MOD QueueSize) + 1;
END
ELSE
Writeln('ERROR--Attempt to serve an empty Q');
END;
END;
(*******************************************************)
(* Random function *)
(* Pre-Cond: a seed has been initialized *)
(* Post-Cond: Random is a uniformly distributed R V *)
(* and a new Seed has been generated. *)
(*******************************************************)
FUNCTION Random(VAR Seed: Integer): Real;
CONST Modulus = 65536;
Multiplier = 25173;
Increment = 13849;
BEGIN
Seed:= ((Multiplier*Seed) + Increment) MOD Modulus;
Random:= Seed/Modulus;
END;
(************************************************************)
(* Pre-Cond: An expected value and a Seed have been pre-set *)
(* Post-Cond: An integer in the range: 0... is generated *)
(* with a poisson distribution *)
(************************************************************)
FUNCTION Poisson(ExpectedValue: Real): Integer;
VAR Limit,
Product: Real;
Count: Integer;
BEGIN
Count:= 0;
Limit:= Exp(-ExpectedValue); (* Exponential function *)
Product:= Random(Seed);
WHILE (Product > Limit) DO
BEGIN
Count:= Count + 1;
Product:= Product*Random(Seed);
END; (*** WHILE ***)
Poisson:= Count;
END;
(******************** End of QueuePack ******************)
(***********************************************************)
(* Pre-Cond: None. *)
(* Post- Cond: All variables are initialized *)
(***********************************************************)
PROCEDURE Initialize;
VAR GoodInput: Boolean;
BEGIN
BackLog := False;
NumberOfPlanes:= 0;
NumberofLandings:= 0;
NumberOfTakeoffs:= 0;
NumberRefused:= 0;
TotalLandingWait:= 0;
TotalTakeoffWait:= 0;
Idletime:= 0;
CurrentTime:=0;
Writeln('This program simulates the activity at an airport with');
Writeln('two runways. Two planes can land or takeoff ');
Writeln('in each time interval of the simulation');
Writeln; Write('How many time periods in the simulation? ');
Readln(EndTime);
Writeln;
Write('Enter a seed integer for the random function: ');
Readln(Seed);
Writeln;
REPEAT
Write('Enter the expected number of arrivals and departures--');
Readln(ExpectedArrivals, ExpectedDepartures); Writeln;
IF ((ExpectedArrivals + ExpectedDepartures) >= 2.0) THEN
Writeln('These must be positive real numbers with total less than 1 ')
ELSE (* Lest the Queues overflow regularly *)
GoodInput:= True;
UNTIL GoodInput;
END; (**************** Initialize *****************************)
(*******************************************************************)
(* Pre-Cond: None. *)
(* Post-Cond: Processes a plane attempting to access a full queue *)
(*******************************************************************)
PROCEDURE Refuse(CurrentPlane: PlaneRecType; VAR NumberRefused: Integer);
BEGIN
Writeln('Queue is full, plane delayed');
NumberRefused:= NumberRefused + 1;
END;
(******************************************************************)
(* Pre-Cond: None. *)
(* Post-Cond: Revises data for landing CurrentPlane *)
(******************************************************************)
PROCEDURE Land(CurrentPlane: PlaneRecType;
CurrentTime: Integer;
VAR NumberLanded,
TotalLandingWait,
MaximumLandingWait: Integer);
VAR WaitingTIme: Integer;
BEGIN
WaitingTime:= CurrentTime - CurrentPlane.TimeOnQ;
TotalLandingWait:= TotalLandingWait + WaitingTime;
If (WaitingTime > MaximumLandingWait) THEN
MaximumLandingWait:= WaitingTime;
NumberofLandings:= NumberofLandings + 1;
Write('Plane #',CurrentPlane.ID:0,' landed at ',CurrentTime:0);
END;
(*****************************************************************)
(* Pre-Cond: None. *)
(* Post-Cond: Process a plane which is taking off. *)
(*****************************************************************)
PROCEDURE Takeoff(CurrentPlane: PlaneRecType;
CurrentTime: Integer;
VAR NumberLanded,
TotalLandingWait,
MaximumLandingWait: Integer);
VAR WaitingTime: Integer;
BEGIN
WaitingTime:= CurrentTime - CurrentPlane.TimeOnQ;
TotalTakeoffWait:= TotalTakeoffWait + WaitingTime;
If (WaitingTime > MaximumTakeoffWait) THEN
MaximumTakeoffWait:= WaitingTime;
NumberofTakeoffs:= NumberofTakeoffs + 1;
Write('Plane #',CurrentPlane.ID:0,' took off at ',CurrentTime:0);
END;
(*****************************************************************)
(* Pre-Cond: None. *)
(* Post-Cond: Updates variables for idle period *)
(*****************************************************************)
PROCEDURE IdleL(CurrentTime: Integer; VAR IdleTimeLand: Integer);
BEGIN
IdleTimeLand:= IdleTimeLand + 1;
Writeln('Runway L is idle at ',CurrentTime:0);
END;
(*****************************************************************)
(* Pre-Cond: None. *)
(* Post-Cond: Updates variables for idle period *)
(*****************************************************************)
PROCEDURE IdleT(CurrentTime: Integer; VAR IdleTimeTakeoff: Integer);
BEGIN
IdleTimeTakeoff:= IdleTimeTakeoff + 1;
Writeln('Runway T is Idle at ',CurrentTime:0);
END;
(*****************************************************************)
(* Pre-Cond: None. *)
(* Post-Cond: Writes out a summary of the activity. *)
(*****************************************************************)
PROCEDURE Conclude(
VAR LandingQ,
TakeoffQ: Queuetype;
VAR CurrentPlane: PlaneRecType;
EndTime,
NumberOfPlanes,
NumberofLandings,
NumberOfTakeoffs,
NumberRefused,
TotalLandingWait,
TotalTakeoffWait,
MaximumLandingWait,
MaximumTakeoffWait,
Idletime: Integer);
BEGIN
Writeln;
IF CurrentTime <= EndTime THEN
Writeln('Simulation has concluded after ',EndTime:0,' units.')
ELSE
Writeln('Simulation has concluded after ',CurrentTime:0,' units.');
Writeln('Total number of planes: ',NumberofPlanes:0);
Writeln(' Number of planes landed: ',NumberofLandings:0);
Writeln(' Number of planes taking off: ',NumberofTakeoffs:0);
Writeln('Number of planes turned away: ',NumberRefused:0);
Writeln;
Writeln(' LANDING WAIT TAKEOFF WAIT');
Writeln('Avg. Max. Avg. Max.');
Writeln;
IF (NumberofLandings = 0) OR (NumberofTakeoffs = 0) THEN
Writeln( 'ZERO DIV')
ELSE
BEGIN
Write(TotalLandingWait/NumberofLandings:2:2, MaximumLandingWait:4);
Writeln(TotalTakeoffWait/NumberofTakeoffs:20:2, MaximumTakeoffWait:4);
END;
Writeln;
Writeln('Percentage of time idle on T: ',IdletimeTakeoff/EndTime*100:2:2);
Writeln;
Writeln('Percentage of time idle on L: ',IdletimeLand/EndTime*100:2:2);
Writeln;
Write('Percentage of time idle: ');
Writeln(((IdletimeLand+IdletimeTakeoff)/EndTime*100)/2:2:2);
Writeln;
END;
(*****************************************************************)
(********************* MAIN ************************************)
(*****************************************************************)
BEGIN
Initialize; (* Many global variables *)
CreateQ(LandingQ);
CreateQ(TakeoffQ);
FOR CurrentTime := 1 to EndTime DO (* Main Loop of Simulation *)
BEGIN
FOR Counter:= 1 TO Poisson(ExpectedArrivals) DO (* Process arrivals *)
BEGIN (* onto Landing queue *)
NumberofPlanes:= NumberofPlanes + 1;
CurrentPlane.ID:= NumberofPlanes;
CurrentPlane.TimeonQ:= CurrentTime;
IF FullQ(LandingQ) THEN
BEGIN
Refuse(CurrentPlane, NumberRefused);
BackLog := True;
END
ELSE
Append(LandingQ, CurrentPlane);
END;
FOR Counter:= 1 TO Poisson(ExpectedDepartures) DO (* Process Departures *)
BEGIN (* onto Takeoff queue *)
NumberofPlanes:= NumberofPlanes + 1;
CurrentPlane.ID:= NumberofPlanes;
CurrentPlane.TimeonQ:= CurrentTime;
IF FullQ(TakeoffQ) THEN
Refuse(Currentplane, NumberRefused)
ELSE
Append(TakeoffQ, CurrentPlane);
END;
IF BackLog AND EmptyQ(LandingQ) THEN
BackLog := False;
IF BackLog AND not EmptyQ(LandingQ) THEN
BEGIN (* First priority to *)
Serve(LandingQ, CurrentPlane); (* planes waiting to land. *)
Land(CurrentPlane, CurrentTime, NumberofLandings,
TotalLandingWait, MaximumLandingWait);
Writeln(' on runway L'); (* Landing on runway L *)
IF not EmptyQ(LandingQ) THEN
BEGIN
Serve(LandingQ, CurrentPlane);
Land(CurrentPlane, CurrentTime, NumberofLandings,
TotalLandingWait, MaximumLandingWait);
Writeln(' on runway T');
END
ELSE
BEGIN
BackLog := False;
IdleL(CurrentTime, IdleTimeLand);
END;
END
ELSE
{===============================================================}
IF not EmptyQ(LandingQ) THEN
BEGIN
Serve(LandingQ, CurrentPlane);
Land(CurrentPlane, CurrentTime, NumberofLandings,
TotalLandingWait, MaximumLandingWait);
Writeln(' on runway L');
IF not EmptyQ(TakeoffQ) THEN
BEGIN
Serve(TakeoffQ, CurrentPlane);
Takeoff(CurrentPlane, CurrentTime, NumberofTakeoffs,
TotalTakeoffWait, MaximumTakeoffWait);
Writeln(' on runway T');
END
ELSE
BEGIN
IF not EmptyQ(LandingQ) THEN
BEGIN
Serve(LandingQ, CurrentPlane);
Land(CurrentPlane, CurrentTime, NumberofLandings,
TotalLandingWait, MaximumLandingWait);
Writeln(' on runway T')
END
ELSE
BEGIN
IdleT(CurrentTime, IdleTimeTakeoff);
END;
END;
END
ELSE
IF not EmptyQ(TakeoffQ) THEN
BEGIN
Serve(TakeoffQ, CurrentPlane);
Takeoff(CurrentPlane, CurrentTime, NumberofTakeoffs,
TotalTakeoffWait, MaximumTakeoffWait);
Writeln(' on runway L');
IF not EmptyQ(TakeoffQ) THEN
BEGIN
Serve(TakeoffQ, CurrentPlane);
Takeoff(CurrentPlane, CurrentTime, NumberofTakeoffs,
TotalTakeoffWait, MaximumTakeoffWait);
Writeln(' on runway T');
END
ELSE
BEGIN
IdleL(CurrentTime, IdleTimeLand);
IdleT(CurrentTime, IdleTimeTakeoff);
END;
END
ELSE
BEGIN
IdleL(CurrentTime, IdleTimeLand);
IdleT(CurrentTime, IdleTimeTakeoff);
END;
END; (************* FOR LOOP ************)
Conclude( (* Write summary statistics *)
LandingQ,
TakeoffQ,
CurrentPlane,
EndTime,
NumberOfPlanes,
NumberofLandings,
NumberOfTakeoffs,
NumberRefused,
TotalLandingWait,
TotalTakeoffWait,
MaximumLandingWait,
MaximumTakeoffWait,
Idletime);
END.